-module (cluster_manager).

-behaviour(gen_server).

-define(SERVER, ?MODULE).


%% API Exports 
-export([start_link/1]).


%% gen_server Function Exports
-export([init/1,
         handle_call/3,
         handle_cast/2,
         handle_info/2,
         terminate/2,
         code_change/3]).

-record(state, {fail}).

-define(FAIL_COUNT, 20).

%%%=============================================================================
%%% API
%%%=============================================================================

%%------------------------------------------------------------------------------
%% @doc
%% Start client manager.
%%
%% @end
%%------------------------------------------------------------------------------
start_link(Cluster) ->
    gen_server:start_link({local, ?SERVER}, ?MODULE, [Cluster], []).
  

%%%=============================================================================
%%% gen_server callbacks
%%%=============================================================================

init([Cluster]) ->
    erlang:send_after(3000, self(), {ping, Cluster}),
    {ok, #state{fail = ?FAIL_COUNT}}.

handle_call(_Request, _From, State) ->
    {reply, ok, State}.

handle_cast(_Msg, State) ->
    {noreply, State}.    

handle_info({ping, Cluster}, State = #state{fail = Fail}) ->
    erlang:send_after(60000, self(), {ping, Cluster}),
    Fail2 = lists:foldl(fun({_, Node, _}, AccIn) ->
        case net_adm:ping(Node) of
            pong ->
                AccIn;
            pang ->
                AccIn - 1
        end 
    end, Fail, Cluster),
    Fail3 = 
    case Fail < 0 of
        true -> 
            %% do send phone message or send mail
            ?FAIL_COUNT;
        false ->
            Fail2
    end,
    {noreply, State#state{fail = Fail3}};

handle_info({'DOWN', _MRef, process, _DownPid, _Reason}, State) ->
    {noreply, State};

handle_info(_Info, State) ->
    {noreply, State}.

terminate(_Reason, _State) ->
    ok.

code_change(_OldVsn, State, _Extra) ->
    {ok, State}.